home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1992-1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- //////////////////////////////////////////////////////////////////////
- // Engine.c++ - implementation of the engine class
- // This is really the "drivetrain" class. It contains everything
- // relating to how the car moves.
- //////////////////////////////////////////////////////////////////////
-
- #include "Simulation.h"
- #include "Driver.h"
- #include "Engine.h"
- #include "Cockpit.h"
- #include "Dynamics.h"
- #include "Road.h"
- #include "Car.h"
- #include "Noise.h"
-
- const int CRANKS_TO_START = 6;
-
- Engine::Engine(Car *c)
- {
- _car = c;
-
- _yaw_per_steering = 0.01;
-
- _max_speed = 220;
- _max_rpm = 8000;
- _redline = 6500;
- _idle = 850;
- _stall = 400;
-
- _compression = 200; // rpms lost per second
- _rpm_per_gas = 4000; // rpms gained per gas per second
-
- _max_fuel = 13.0;
- _mileage = 30.0;
- _max_oil = 120.0;
- _max_temp = 200.0;
-
- _tire_diam = 2.0;
-
- // Axel revs per Engine rev
- // XXX reverse?
- _ratio[0] = 0.0;
- _ratio[1] = 0.047;
- _ratio[2] = .10;
- _ratio[3] = .163;
- _ratio[4] = .280;
- _ratio[5] = .373;
-
- // initialize noises to NULL so when can see if they need
- // to be destroyed in the destuctor
- // XXX shouldn't this happen by default?
- _revving_noise = NULL;
- _starting_noise = _cranking_noise = _caf_caf = NULL;
-
- // max time, usecs
- if ((_car->get_type() == LOCAL_CAR) &&
- (_car->get_simulation()->sound_capable()))
- {
- SbString motorpath(_car->get_simulation()->get_path().getString());
- SbString motorfile("motor_loop.aiff");
- motorpath += motorfile;
-
- _revving_noise = new Noise(motorpath.getString(),
- 125000, _car->get_simulation()->play_sound());
-
- SbString startpath(_car->get_simulation()->get_path().getString());
- SbString startfile("start_to_crank.aiff");
- startpath += startfile;
-
- _starting_noise = readsample(startpath.getString());
-
- SbString crankpath(_car->get_simulation()->get_path().getString());
- SbString crankfile("crank_loop.aiff");
- crankpath += crankfile;
-
- _cranking_noise = readsample(crankpath.getString());
-
- SbString cafpath(_car->get_simulation()->get_path().getString());
- SbString caffile("caf_caf.aiff");
- cafpath += caffile;
-
- _caf_caf = readsample(cafpath.getString());
- }
-
- reset_all();
- }
-
-
- void Engine::reset_all()
- {
- stall(FALSE);
-
- _gear = 0;
- _fuel = _max_fuel;
- _oil = 0.7*_max_oil;
- _temp = 0.3*_max_temp;
- }
-
-
- Engine::~Engine()
- {
- // they may not have been read, so check if they exist before deletion
- if (_revving_noise) delete _revving_noise;
- if (_starting_noise) freesample(_starting_noise);
- if (_cranking_noise) freesample(_cranking_noise);
- if (_caf_caf) freesample(_caf_caf);
- }
-
-
- void Engine::crank(Boolean ignition)
- {
- static int num_cranks = 0;
-
- if (_running || (! ignition))
- {
- num_cranks = 0;
- return;
- }
-
- if (_starting_noise && _cranking_noise &&
- _car->get_simulation()->play_sound())
- {
- if (num_cranks == 0)
- playsample(_starting_noise);
-
- playsample(_cranking_noise);
- }
-
-
- if ((++num_cranks >= CRANKS_TO_START) &&
- (_car->get_driver()->get_cockpit()->get_gas() > 0.0))
- {
- num_cranks = 0;
- _running = TRUE;
- if (_revving_noise)
- _revving_noise->setContinuity(TRUE);
- }
-
- }
-
-
- /*
- RPMs are affected by gas, engine compression and friction, and velocity
-
- Velocity is affected by RPMs/Gear, brakes, gravity, and friction (wheel/road
- and air).
-
- Thus we have a feedback loop. The current RPMs are based on the last
- velocity. The current velocity is then based on the current RPMs.
- */
- void Engine::update()
- {
- if (! _running)
- return;
-
- float fps = _car->get_simulation()->get_fps();
-
- // rpms based on velocity only if not in neutral
- if (_gear != 0)
- {
- _rpm = (int)
- (_car->get_dynamics()->get_velocity()/(60.0 *
- this->get_ratio() * this->get_tire_diam() *
- (1.0/_car->get_road()->get_distance_factor()) * M_PI));
- }
-
- //printf("\nrpm = %d\n",_rpm);
-
- // add gas
- // gas is specified as rpms added per second per gas
- _rpm +=
- (int)((((float)_rpm_per_gas - 750.0*(float)_gear)/fps)*_car->get_driver()->get_cockpit()->get_gas());
-
- //printf("rpm = %d\n",_rpm);
-
- // subtract engine compression
- // compression is specified as loss of rpm per second
- _rpm -= (int)((float)_compression*(6.0 - (float)_gear)/fps);
-
- //printf("rpm = %d\n",_rpm);
-
- if ( ((_gear == 0) || (_gear == 1)) && (_rpm < _idle))
- _rpm = _idle;
- else if (_rpm < _stall)
- stall(_car->get_simulation()->play_sound());
- else if (_rpm > _max_rpm)
- // XXX Engine blowout
- _rpm = _max_rpm;
-
- if (_revving_noise && _car->get_simulation()->play_sound())
- _revving_noise->play(
- .5 + ((float)_rpm/(float)_idle)/3.0, // just sounds good
- _car->get_driver()->last_frame_time());
-
-
- }
-
-
- void Engine::stall(Boolean noise)
- {
- if (_caf_caf && noise)
- playsample(_caf_caf);
-
- _rpm = 0;
- _running = FALSE;
- if (_revving_noise)
- _revving_noise->setContinuity(FALSE);
- }
-
-
- // returns TRUE if the engine rpms are changing, false
- // if rpms are the same as the last time this was called
- Boolean Engine::revving() const
- {
- static int last_rpm = _idle;
- Boolean result;
-
- result = (_rpm != last_rpm);
-
- last_rpm = _rpm;
-
- return result;
- }
-
- void Engine::upshift()
- {
- if (++_gear > 5)
- _gear = 5;
- }
-
- void Engine::downshift()
- {
- if (--_gear < 0)
- _gear = 0;
- }
-
-
- void Engine::set_sound(Boolean b)
- {
- if (_revving_noise)
- _revving_noise->setContinuity(b);
- }
-